'use strict';

module.exports = core;

const pkg = require('../package.json');
const log = require('@dou-gong-cli/log');
const constant = require('./const');
const semver = require('semver');
const colors = require('colors');
const { homedir } = require('os');
const path = require('path');
const pathExistsSync = require('path-exists').sync;
const { getNpmSemverVersion } = require('@dou-gong-cli/get-npm-info');
const init = require('@dou-gong-cli/init');
const commander = require('commander');
const exec = require('@dou-gong-cli/exec');

/** 初始化command实例 */
const program = new commander.Command();

/** 核心执行函数 */
async function core() {
  try {
    await prepare();
    registCommander();
  } catch (e) {
    log.error('core', e);
  }
}

async function prepare() {
  checkPkgVersion();
  checkRoot();
  checkUserHome();
  checkEnv();
  await checkGlobalUpdate();
}

/** 检查脚手架版本 */
function checkPkgVersion() {
  const version = pkg.version;
  // log.info('cli', `checked version ${version}`);
}

/** 检查当前是否是管理员 */
function checkRoot() {
  const rootCheck = require('root-check');
  rootCheck();
}

/** 检查当前目录是否使用户目录 */
function checkUserHome() {
  const userHome = homedir();
  if (!userHome || !pathExistsSync(userHome)) {
    throw new Error(colors.red('当前用户主目录不存在！'));
  }
}

/** 检查环境变量，并将全局环境变量写入process.env */
function checkEnv() {
  const dotenv = require('dotenv');
  const dorenvPath = path.resolve(homedir(), '.dg-env');
  let config;
  if (pathExistsSync(dorenvPath)) {
    config = dotenv.config({ path: dorenvPath }).parsed;
  } else {
    config = createDefaultConfig();
  }
}

/** 创建cli默认配置 */
function createDefaultConfig() {
  const cliConfig = {
    home: homedir()
  };

  cliConfig['CLI_HOME'] = path.join(
    homedir(),
    process.env.CLI_HOME || constant.DEFAULT_CLI_HOME
  );
  process.env.DG_CLI_HOME_PATH = cliConfig.CLI_HOME;
  return cliConfig;
}

/** 检查当前npm包是否为最新版本 */
async function checkGlobalUpdate() {
  // 1. 获取当前版本号和模块名
  // 2. 获取线上所有的版本号
  // 3. 比对那些版本号是大于当前版本号
  // 4. 获取最新的版本号，提示用户更新到最新的版本
  const currentVersion = pkg.version;
  const pkgName = pkg.name;
  const lastVersion = await getNpmSemverVersion(currentVersion, pkgName);
  if (lastVersion && semver.gt(lastVersion, currentVersion)) {
    log.warn(
      'update',
      colors.yellow(
        [
          `请手动更新 ${pkgName}，当前版本：${currentVersion}，最新版本：${lastVersion}`,
          `更新命令 npm install ${pkgName}`
        ].join('\n')
      )
    );
  }
}

/** 注册脚手架 */
function registCommander() {
  /** 全局
  -------------------------------------- */
  program
    .name('dg')
    .version(pkg.version, '-v, -V, --veriosion', '显示版本号')
    .option('-d, --debug', '开启debug模式', false)
    .option('-tp, --targetPath <targetPath>', '是否指定本地调试文件', '')
    .usage('<command> [option]');

  /** init
  -------------------------------------- */
  program
    .command('init [projectName]')
    // .description('初始化项目')
    .option('-f, --force', '强制初始化')
    .action(exec);

  // ----------------------- 参数监听 start ----------------------- //
  // debug 参数监听处理
  program.on('option:debug', () => {
    process.env.LOG_LEVEL = program.opts()['debug'] ? 'verbose' : 'info';
    log.level = process.env.LOG_LEVEL;
  });

  // 监听tp
  program.on('option:targetPath', () => {
    process.env.DG_CLI_TARGET_PATH = program.opts()['targetPath'];
  });

  // 对未知命令的监听
  program.on('command:*', (cmd) => {
    const availableCommands = program.commands.map((cmd) => cmd.name());
    console.log(colors.red(`未知的命令：${cmd[0]}`));
    if (availableCommands.length > 0) {
      console.log(colors.green(`可用命令：${availableCommands.join(', ')}`));
    }
  });
  // ------------------------ 参数监听 end ------------------------ //

  if (process.env.length < 3) {
    program.outputHelp();
  }

  program.parse(process.argv);
}
